home *** CD-ROM | disk | FTP | other *** search
/ Cream of the Crop 1 / Cream of the Crop 1.iso / PROGRAM / DJLSR106.ARJ / IOSTREAM.CC < prev    next >
C/C++ Source or Header  |  1992-03-30  |  16KB  |  719 lines

  1. //    This is part of the iostream library, providing input/output for C++.
  2. //    Copyright (C) 1991 Per Bothner.
  3. //
  4. //    This library is free software; you can redistribute it and/or
  5. //    modify it under the terms of the GNU Library General Public
  6. //    License as published by the Free Software Foundation; either
  7. //    version 2 of the License, or (at your option) any later version.
  8. //
  9. //    This library is distributed in the hope that it will be useful,
  10. //    but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. //    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  12. //    Library General Public License for more details.
  13. //
  14. //    You should have received a copy of the GNU Library General Public
  15. //    License along with this library; if not, write to the Free
  16. //    Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  17.  
  18. #ifdef __GNUG__
  19. #pragma implementation "iostream.h"
  20. #endif
  21. #define _STREAM_COMPAT
  22. #include "ioprivate.h"
  23. #include <iostream.h>
  24. #include <stdio.h>  /* Needed for sprintf */
  25. #include <ctype.h>
  26. #include "floatio.h"
  27.  
  28. #define    BUF        (MAXEXP+MAXFRACT+1)    /* + decimal point */
  29.  
  30. //#define isspace(ch) ((ch)==' ' || (ch)=='\t' || (ch)=='\n')
  31.  
  32. extern streambuf not_open_filebuf;
  33.  
  34. istream::istream() : ios(¬_open_filebuf)
  35. {
  36.     _flags |= ios::dont_close;
  37.     _gcount = 0;
  38.     _tie = NULL;
  39. }
  40.  
  41. istream::istream(streambuf *sb, ostream* tied) : ios(sb)
  42. {
  43.     _flags |= ios::dont_close;
  44.     _gcount = 0;
  45.     _tie = tied;
  46. }
  47.  
  48. istream::~istream()
  49. {
  50.     if (!(_flags & (unsigned int)ios::dont_close))
  51.     delete _strbuf;
  52.     _flags |= ios::dont_close;
  53.     _strbuf = ¬_open_filebuf;
  54. }
  55.  
  56. int skip_ws(streambuf* sb)
  57. {
  58.     int ch;
  59.     for (;;) {
  60.     ch = sb->sbumpc();
  61.     if (ch == EOF || !isspace(ch))
  62.         return ch;
  63.     }
  64. }
  65.  
  66. istream& istream::get(char& c)
  67. {
  68.     if (ipfx1()) {
  69.     int ch = _strbuf->sbumpc();
  70.     if (ch == EOF) set(ios::eofbit|ios::failbit);
  71.     else c = (char)ch;
  72.     }
  73.     return *this;
  74. }
  75.  
  76. istream& istream::get(unsigned char& c)
  77. {
  78.     if (ipfx1()) {
  79.     int ch = _strbuf->sbumpc();
  80.     if (ch == EOF) set(ios::eofbit|ios::failbit);
  81.     else c = (unsigned char)ch;
  82.     }
  83.     return *this;
  84. }
  85.  
  86. istream& istream::ignore(int n=1, int delim = EOF)
  87. {
  88.     if (ipfx0()) {
  89.     register streambuf* sb = _strbuf;
  90.     for (;;) {
  91.         // Could skip multiple chars at a time if egptr() > gptr(),
  92.         // if delim==EOF. FIXME!
  93. #if 0
  94.         if (n != MAXINT) // FIXME
  95. #endif
  96.         if (--n < 0)
  97.         break;
  98.         int ch = sb->sbumpc();
  99.         if (ch == EOF) {
  100.         set(ios::eofbit|ios::failbit);
  101.         break;
  102.         }
  103.         else if (ch == delim)
  104.         break;
  105.     }
  106.     }
  107.     return *this;
  108. }
  109.  
  110. istream& istream::read(char *s, int n)
  111. {
  112.     if (ipfx1()) {
  113.     if (_strbuf->sgetn(s, n) != n)
  114.         set(ios::failbit);
  115.     }
  116.     return *this;
  117. }
  118.  
  119. istream& istream::seekg(streampos pos)
  120. {
  121.     pos = _strbuf->seekpos(pos, ios::in);
  122.     if (pos == streampos(EOF))
  123.     set(ios::badbit);
  124.     return *this;
  125. }
  126.  
  127. istream& istream::seekg(streamoff off, _seek_dir dir)
  128. {
  129.     streampos pos = _strbuf->seekoff(off, dir, ios::in);
  130.     if (pos == streampos(EOF))
  131.     set(ios::badbit);
  132.     return *this;
  133. }
  134.  
  135. streampos istream::tellg()
  136. {
  137.     streampos pos = _strbuf->seekoff(0, ios::cur, ios::in);
  138.     if (pos == streampos(EOF))
  139.     set(ios::badbit);
  140.     return pos;
  141. }
  142.  
  143. istream& operator>>(istream& is, char& c)
  144. {
  145.     if (is.ipfx0()) {
  146.     int ch = is._strbuf->sbumpc();
  147.     if (ch == EOF)
  148.         is.set(ios::eofbit|ios::failbit);
  149.     else
  150.         c = (char)ch;
  151.     }
  152.     return is;
  153. }
  154.  
  155. istream& operator>>(istream& is, unsigned char& c)
  156. {
  157.     if (is.ipfx0()) {
  158.     int ch = is._strbuf->sbumpc();
  159.     if (ch == EOF)
  160.         is.set(ios::eofbit|ios::failbit);
  161.     else
  162.         c = (unsigned char)ch;
  163.     }
  164.     return is;
  165. }
  166.  
  167. istream& operator>>(istream& is, char* ptr)
  168. {
  169.     if (is.ipfx0()) {
  170.     register streambuf* sb = is._strbuf;
  171.     int ch = sb->sbumpc();
  172.     if (ch == EOF)
  173.         is.set(ios::eofbit|ios::failbit);
  174.     else {
  175.         int w = is.width(0);
  176.         *ptr++ = ch;
  177.         for (;;) {
  178.         ch = sb->sbumpc();
  179.         if (ch == EOF) {
  180.             is.set(ios::eofbit|ios::failbit);
  181.             break;
  182.         }
  183.         else if (isspace(ch)) {
  184.             sb->sputbackc(ch);
  185.             break;
  186.         }
  187.         else if (w == 1) {
  188.             is.set(ios::failbit);
  189.             sb->sputbackc(ch);
  190.             break;
  191.         }
  192.         else *ptr++ = ch;
  193.         w--;
  194.         }
  195.     }
  196.     }
  197.     *ptr = '\0';
  198.     return is;
  199. }
  200.  
  201. static int read_int(istream& stream, unsigned long& val, int& neg)
  202. {
  203.     if (!stream.ipfx0())
  204.     return 0;
  205.     register streambuf* sb = stream.rdbuf();
  206.     int base = 10;
  207.     int ndigits = 0;
  208.     register int ch = skip_ws(sb);;
  209.     if (ch == EOF)
  210.     goto eof_fail;
  211.     neg = 0;
  212.     if (ch == '+') {
  213.     ch = skip_ws(sb);
  214.     }
  215.     else if (ch == '-') {
  216.     neg = 1;
  217.     ch = skip_ws(sb);
  218.     }
  219.     if (ch == EOF) goto eof_fail;
  220.     if (!(stream.flags() & (ios::hex|ios::dec|ios::oct))) {
  221.     if (ch == '0') {
  222.         ch = sb->sbumpc();
  223.         if (ch == EOF) {
  224.         val = 0;
  225.         return 1;
  226.         }
  227.         if (ch == 'x' || ch == 'X') {
  228.         base = 16;
  229.         ch = sb->sbumpc();
  230.         if (ch == EOF) goto eof_fail;
  231.         }
  232.         else {
  233.         sb->sputbackc(ch);
  234.         base = 8;
  235.         ch = '0';
  236.         }
  237.     }
  238.     }
  239.     else if (stream.flags() & ios::hex)
  240.     base = 16;
  241.     else if (stream.flags() & ios::oct)
  242.     base = 8;
  243.     val = 0;
  244.     for (;;) {
  245.     if (ch == EOF)
  246.         break;
  247.     int digit;
  248.     if (ch >= '0' && ch <= '9')
  249.         digit = ch - '0';
  250.     else if (ch >= 'A' && ch <= 'F')
  251.         digit = ch - 'A' + 10;
  252.     else if (ch >= 'a' && ch <= 'f')
  253.         digit = ch - 'a' + 10;
  254.     else
  255.         digit = 999;
  256.     if (digit >= base)
  257.         if (ndigits == 0)
  258.         goto fail;
  259.         else {
  260.         sb->sputbackc(ch);
  261.         return 1;
  262.         }
  263.     ndigits++;
  264.     val = base * val + digit;
  265.     ch = sb->sbumpc();
  266.     }
  267.     return 1;
  268.   fail:
  269.     stream.set(ios::failbit);
  270.     return 0;
  271.   eof_fail:
  272.     stream.set(ios::failbit|ios::eofbit);
  273.     return 0;
  274. }
  275.  
  276. #define READ_INT(TYPE) \
  277. istream& operator>>(istream& is, TYPE& i)\
  278. {\
  279.     unsigned long val; int neg;\
  280.     if (read_int(is, val, neg)) {\
  281.     if (neg) val = -val;\
  282.     i = (TYPE)val;\
  283.     }\
  284.     return is;\
  285. }
  286.  
  287. READ_INT(short)
  288. READ_INT(unsigned short)
  289. READ_INT(int)
  290. READ_INT(unsigned int)
  291. READ_INT(long)
  292. READ_INT(unsigned long)
  293.  
  294. istream& operator>>(istream& is, double& x)
  295. {
  296.     if (is.ipfx0()) {
  297.     double* ptr = &x;
  298.     is.rdbuf()->vscan("%lg", (_G_va_list)&ptr);
  299.     }
  300.     return is;
  301. }
  302. istream& operator>>(istream& is, float& x)
  303. {
  304.     if (is.ipfx0()) {
  305.     float* ptr = &x;
  306.     is.rdbuf()->vscan("%g", (_G_va_list)&ptr);
  307.     }
  308.     return is;
  309. }
  310.  
  311. ostream& operator<<(ostream& os, char c)
  312. {
  313.     if (os.opfx()) {
  314.     int w = os.width(0);
  315.     char fill_char = os.fill();
  316.     register int padding = w > 0 ? w - 1 : 0;
  317.     register streambuf *sb = os._strbuf;
  318.     if (!(os.flags() & ios::left)) // Default adjustment.
  319.         while (--padding >= 0) sb->sputc(fill_char);
  320.     sb->sputc(c);
  321.     if (os.flags() & ios::left) // Left adjustment.
  322.         while (--padding >= 0) sb->sputc(fill_char);
  323.     os.osfx();
  324.     }
  325.     return os;
  326. }
  327.  
  328. void write_int(ostream& stream, unsigned long val, int neg)
  329. {
  330.     char buf[10 + sizeof(unsigned long) * 3];
  331.     char *show_base = "";
  332.     int show_base_len = 0;
  333.     if ((stream.flags() & (ios::oct|ios::hex)) == 0) // Decimal
  334.     sprintf(buf, "%lu", val);
  335.     else if (stream.flags() & ios::oct) { // Oct
  336.     sprintf(buf, "%lo", val);
  337.     if (stream.flags() && ios::showbase)
  338.         show_base = "0", show_base_len = 1;
  339.     }
  340.     else if (stream.flags() & ios::uppercase) {// Hex
  341.     sprintf(buf, "%lX", val);
  342.     if (stream.flags() && ios::showbase)
  343.         show_base = "0X", show_base_len = 2;
  344.     }
  345.     else { // Hex
  346.     sprintf(buf, "%lx", val);
  347.     if (stream.flags() && ios::showbase)
  348.         show_base = "0x", show_base_len = 2;
  349.     }
  350.     int buf_len = strlen(buf);
  351.     int w = stream.width(0);
  352.     int show_pos = 0;
  353.     int i;
  354.  
  355.     // Calculate padding.
  356.     int len = buf_len;
  357.     if (neg) len++;
  358.     else if (val != 0 && (stream.flags() & ios::showpos)) len++, show_pos=1;
  359.     len += show_base_len;
  360.     int padding = len > w ? 0 : w - len;
  361.  
  362.     // Do actual output.
  363.     register streambuf* sbuf = stream.rdbuf();
  364.     unsigned long pad_kind =
  365.     stream.flags() & (ios::left|ios::right|ios::internal);
  366.     char fill_char = stream.fill();
  367.     if (pad_kind != (unsigned long)ios::left // Default (right) adjustment.
  368.     && pad_kind != (unsigned long)ios::internal)
  369.     for (i = padding; --i >= 0; ) sbuf->sputc(fill_char);
  370.     if (neg) sbuf->sputc('-');
  371.     else if (show_pos) sbuf->sputc('+');
  372.     if (show_base_len)
  373.     sbuf->sputn(show_base, show_base_len);
  374.     if (pad_kind == (unsigned long)ios::internal)
  375.     for (i = padding; --i >= 0; ) sbuf->sputc(fill_char);
  376.     sbuf->sputn(buf, buf_len);
  377.     if (pad_kind == (unsigned long)ios::left) // Left adjustment.
  378.     for (i = padding; --i >= 0; ) sbuf->sputc(fill_char);
  379.     stream.osfx();
  380. }
  381.  
  382. ostream& operator<<(ostream& os, int n)
  383. {
  384.     if (os.opfx()) {
  385.     int neg = 0;
  386.     if (n < 0 && (os.flags() & (ios::oct|ios::hex)) == 0)
  387.         n = -n, neg = 1;
  388.     write_int(os, n, neg);
  389.     }
  390.     return os;
  391. }
  392.  
  393. ostream& operator<<(ostream& os, long n)
  394. {
  395.     if (os.opfx()) {
  396.     int neg = 0;
  397.     if (n < 0 && (os.flags() & (ios::oct|ios::hex)) == 0)
  398.         n = -n, neg = 1;
  399.     write_int(os, n, neg);
  400.     }
  401.     return os;
  402. }
  403.  
  404. ostream& operator<<(ostream& os, unsigned int n)
  405. {
  406.     if (os.opfx())
  407.     write_int(os, n, 0);
  408.     return os;
  409. }
  410.  
  411. ostream& operator<<(ostream& os, unsigned long n)
  412. {
  413.     if (os.opfx())
  414.     write_int(os, n, 0);
  415.     return os;
  416. }
  417.  
  418. ostream& operator<<(ostream& os, float n)
  419. {
  420.     return os << (double)n;
  421. }
  422.  
  423. ostream& operator<<(ostream& os, double n)
  424. {
  425.     if (os.opfx()) {
  426.     // Uses __cvt_double (renamed from static cvt), in Chris Torek's
  427.     // stdio implementation.  The setup code uses the same logic
  428.     // as in __vsbprintf.C (also based on Torek's code).
  429.     char negative;
  430.     char buf[BUF];
  431.     int format_char;
  432.     int sign = '\0';
  433. #if 0
  434.     if (os.flags() ios::showpos) sign = '+';
  435. #endif
  436.     if (os.flags() & ios::fixed)
  437.         format_char = 'f';
  438.     else if (os.flags() & ios::scientific)
  439.         format_char = os.flags() & ios::uppercase ? 'E' : 'e';
  440.     else
  441.         format_char = os.flags() & ios::uppercase ? 'G' : 'g';
  442.  
  443.     int fpprec = 0; // 'Extra' (suppressed) floating precision.
  444.     int prec = os.precision();
  445.     if (prec < 0) prec = 6; // default.
  446.     else if (prec > MAXFRACT) {
  447.         if (os.flags() & (ios::fixed|ios::scientific) & ios::showpos)
  448.         fpprec = prec - MAXFRACT;
  449.         prec = MAXFRACT;
  450.     }
  451.  
  452.     // Do actual conversion.
  453.     char *cp = buf;
  454.     *cp = 0;
  455.     int size = __cvt_double(n, os.precision(),
  456.                 os.flags() & ios::showpoint ? 0x80 : 0,
  457.                 &negative,
  458.                 format_char, cp, buf + sizeof(buf));
  459.     if (negative) sign = '-';
  460.     if (*cp == 0)
  461.         cp++;
  462.  
  463.     // Calculate padding.
  464.     int fieldsize = size + fpprec;
  465.     if (sign) fieldsize++;
  466.     int padding = 0;
  467.     int w = os.width(0);
  468.     if (fieldsize < w)
  469.         padding = w - fieldsize;
  470.  
  471.     // Do actual output.
  472.     register streambuf* sbuf = os.rdbuf();
  473.     register i;
  474.     char fill_char = os.fill();
  475.     unsigned long pad_kind =
  476.         os.flags() & (ios::left|ios::right|ios::internal);
  477.     if (pad_kind != (unsigned long)ios::left // Default (right) adjust.
  478.         && pad_kind != (unsigned long)ios::internal)
  479.         for (i = padding; --i >= 0; ) sbuf->sputc(fill_char);
  480.     if (sign)
  481.         sbuf->sputc(sign);
  482.     if (pad_kind == (unsigned long)ios::internal)
  483.         for (i = padding; --i >= 0; ) sbuf->sputc(fill_char);
  484.     
  485.     // Emit the actual concented field, followed by extra zeros.
  486.     sbuf->sputn(cp, size);
  487.     for (i = fpprec; --i >= 0; ) sbuf->sputc('0');
  488.  
  489.     if (pad_kind == (unsigned long)ios::left) // Left adjustment
  490.         for (i = padding; --i >= 0; ) sbuf->sputc(fill_char);
  491.     os.osfx();
  492.     }
  493.     return os;
  494. }
  495.  
  496. ostream& operator<<(ostream& stream, const char *s)
  497. {
  498.     if (stream.opfx()) {
  499.     int len = strlen(s);
  500.     int w = stream.width(0);
  501.     char fill_char = stream.fill();
  502.     register streambuf *sbuf = stream.rdbuf();
  503.     register int padding = w > len ? w - len : 0;
  504.     if (!(stream.flags() & ios::left)) // Default adjustment.
  505.         while (--padding >= 0) sbuf->sputc(fill_char);
  506.     sbuf->sputn(s, len);
  507.     if (stream.flags() & ios::left) // Left adjustment.
  508.         while (--padding >= 0) sbuf->sputc(fill_char);
  509.     stream.osfx();
  510.     }
  511.     return stream;
  512. }
  513.  
  514. ostream& operator<<(ostream& os, void *p)
  515. {
  516.     if (os.opfx()) {
  517.     void *px = p;
  518.     os._strbuf->vform("0x%x", (_G_va_list)&px);
  519.     os.osfx();
  520.     }
  521.     return os;
  522. }
  523.  
  524. ostream& operator<<(ostream& os, register streambuf* sbuf)
  525. {
  526.     if (os.opfx()) {
  527.     register streambuf* outbuf = os.rdbuf();
  528.     // FIXME: Should optimize!
  529.     for (;;) {
  530.         register int ch = sbuf->sbumpc();
  531.         if (ch == EOF) break;
  532.         outbuf->sputc(ch);
  533.     }
  534.     os.osfx();
  535.     }
  536.     return os;
  537. }
  538.  
  539. ostream::ostream() : ios(¬_open_filebuf)
  540. {
  541.     _flags |= ios::dont_close;
  542.     _tie = NULL;
  543. }
  544.  
  545. ostream::ostream(streambuf* sb, ostream* tied) : ios(sb)
  546. {
  547.     _flags |= ios::dont_close;
  548.     _tie = tied;
  549. }
  550.  
  551. ostream::~ostream()
  552. {
  553.     if (!(_flags & (unsigned int)ios::dont_close))
  554.     delete _strbuf;
  555.     _flags |= ios::dont_close;
  556.     _strbuf = ¬_open_filebuf;
  557. }
  558.  
  559. ostream& ostream::seekp(streampos pos)
  560. {
  561.     pos = _strbuf->seekpos(pos, ios::out);
  562.     if (pos == streampos(EOF))
  563.     set(ios::badbit);
  564.     return *this;
  565. }
  566.  
  567. ostream& ostream::seekp(streamoff off, _seek_dir dir)
  568. {
  569.     streampos pos = _strbuf->seekoff(off, dir, ios::out);
  570.     if (pos == streampos(EOF))
  571.     set(ios::badbit);
  572.     return *this;
  573. }
  574.  
  575. streampos ostream::tellp()
  576. {
  577.     streampos pos = _strbuf->seekoff(0, ios::cur, ios::out);
  578.     if (pos == streampos(EOF))
  579.     set(ios::badbit);
  580.     return pos;
  581. }
  582.  
  583. ostream& ostream::form(const char *format ...)
  584. {
  585.     va_list ap;
  586.     va_start(ap, format);
  587.     _strbuf->vform(format, (_G_va_list)ap);
  588.     va_end(ap);
  589.     return *this;
  590. }
  591.  
  592. ostream& ostream::vform(const char *format, _G_va_list args)
  593. {
  594.     _strbuf->vform(format, args);
  595.     return *this;
  596. }
  597.  
  598. ostream& ostream::flush()
  599. {
  600.     if (_strbuf->sync())
  601.     set(ios::badbit);
  602.     return *this;
  603. }
  604.  
  605. ostream& flush(ostream& outs)
  606. {
  607.     outs.rdbuf()->overflow(EOF);
  608.     return outs;
  609. }
  610.  
  611. istream& ws(istream& ins)
  612. {
  613.     if (ins.ipfx1())
  614.     for (;;) {
  615.         int ch = ins._strbuf->sbumpc();
  616.         if (ch == EOF) {
  617.         ins.set(ios::eofbit);
  618.         break;
  619.         }
  620.         if (!isspace(ch)) {
  621.         ins._strbuf->sputbackc(ch);
  622.         break;
  623.         }
  624.     }
  625.     return ins;
  626. }
  627.  
  628. ostream& ends(ostream& outs)
  629. {
  630.     outs.put(0);
  631.     return outs;
  632. }
  633.  
  634. ostream& endl(ostream& outs)
  635. {
  636.     return flush(outs.put('\n'));
  637. }
  638.  
  639. ostream& ostream::write(const char *s, int n)
  640. {
  641.     if (opfx()) {
  642.     if (_strbuf->sputn(s, n) != n)
  643.         set(ios::failbit);
  644.     }
  645.     return *this;
  646. }
  647.  
  648. void ostream::do_osfx()
  649. {
  650.     if (flags() & ios::unitbuf)
  651.     flush();
  652.     if (flags() & ios::stdio) {
  653.     fflush(stdout);
  654.     fflush(stderr);
  655.     }
  656. }
  657.  
  658. const unsigned long ios::basefield = ios::hex|ios::oct|ios::dec;
  659. const unsigned long ios::floatfield = ios::scientific|ios::fixed;
  660. const unsigned long ios::adjustfield =
  661.     ios::left|ios::right|ios::internal;
  662.  
  663. iostream::iostream() : ios(¬_open_filebuf)
  664. {
  665.     _flags |= ios::dont_close;
  666.     _gcount = 0;
  667.     _tie = NULL;
  668. }
  669.  
  670. iostream::iostream(streambuf* sb, ostream* tied) : ios(sb)
  671. {
  672.     _flags |= ios::dont_close;
  673.     _tie = tied;
  674. }
  675.  
  676. iostream::~iostream()
  677. {
  678.     if (!(_flags & (unsigned int)ios::dont_close))
  679.     delete _strbuf;
  680.     _flags |= ios::dont_close;
  681.     _strbuf = ¬_open_filebuf;
  682. }
  683.  
  684. ostream& iostream::form(const char *format ...) // Copy of ostream::form.
  685. {
  686.     va_list ap;
  687.     va_start(ap, format);
  688.     _strbuf->vform(format, (_G_va_list)ap);
  689.     va_end(ap);
  690.     return *(ostream*)this;
  691. }
  692.  
  693. // NOTE: extension for compatibility with old libg++.
  694. // Not really compatible with fistream::close().
  695. #ifdef _STREAM_COMPAT
  696. void ios::close()
  697. {
  698.     if (!(_flags & (unsigned int)ios::dont_close))
  699.     delete _strbuf;
  700.     else if (_strbuf->_flags & _S_IS_FILEBUF)
  701.     ((struct filebuf*)_strbuf)->close();
  702.     else if (_strbuf != ¬_open_filebuf)
  703.     _strbuf->sync();
  704.     _flags |= ios::dont_close;
  705.     _strbuf = ¬_open_filebuf;
  706. }
  707.  
  708. int istream::skip(int i)
  709. {
  710.     int old = (_flags & ios::skipws) != 0;
  711.     if (i)
  712.     _flags |= ios::skipws;
  713.     else
  714.     _flags &= ~ios::skipws;
  715.     return old;
  716. }
  717. #endif
  718.  
  719.